#ifndef IA32VBASICBLOCKBUILDER_H
#define IA32VBASICBLOCKBUILDER_H

#include "crossbit/VBasicBlockBuilder.h"
#include "crossbit/VBlock.h"
#include "crossbit/VInst.h"
#include "arch/ia32/IA32Interpreter.h"
#include "deque"
#include "vector"

namespace crossbit {

    enum FLAGS{
        REGDEF,
        REGUSE,
        REGNONE
    }; 

    class IA32VBasicBlockBuilder : public VBasicBlockBuilder {
        public:
            IA32VBasicBlockBuilder(){
                flagInfo.clear();
                ftop = 1;			// f0 always zero
            }

            ~IA32VBasicBlockBuilder()
            {
            }

            void getReady(XTMemAddr pc ){
                VBasicBlockBuilder::getReady(pc);
                flagInfo.clear();
                ftop = 1;
            }
            virtual void add(VInst *inst)
            {
                Opcode opcode = inst->getOpcode();
                Opkind opkind = inst->getOpkind();

                if ( opcode == OP_SYSCALL			||
                     opkind == OPK_CONTROLTRANSFER	||
                     opcode == OP_HALT)
                {
                    bb_end = true;
                }


                bb_vblock->push_back(inst);

                if (opcode == OP_CALL)
                {
                    bb_vblock->setFlagsCount(bb_vblock->getFlagsCount() + 1);
                }
                bb_vblock->setTotalCount(bb_vblock->getTotalCount() + 1);
            }

            VBlock *wrapUp(MemAddr pc) 
            {
                std::vector<VInst *>::iterator it = bb_vblock->begin();

                while( it != bb_vblock->end() )
                {
                    if( *it == NULL )
                    {
                        it = bb_vblock->erase(it);
                    }
                    else
                        ++it;
                }
                ftop = 1;
                return VBasicBlockBuilder::wrapUp(pc);
            }

            // added by zhangyichao
            inline XTInt32 getFtop()
            {
                return ftop;
            }

            // added by zhangyichao
            void incFtop()
            {
                ftop++;
                assert((ftop >= 1) && (ftop <= 8));
            }

            // added by zhangyichao
            void decFtop()
            {
                ftop--;
                assert((ftop >= 1) && (ftop <= 8));
            }

        private:
            std::vector<FLAGS>  flagInfo;
            XTInt32 ftop;   // added by zhangyichao for vf_regs alloc in interpreter
    };


}

#endif
